#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<Winsock2.h>

#pragma comment(lib, "Ws2_32")

int ParseFileSize(FILE* file, SOCKET soc, int& size_written) {
  const int kRecvBufSize = 1024;
  char RecvBuf[kRecvBufSize] = {'\0'};
  int result = recv(soc, RecvBuf, kRecvBufSize, 0);

  int size = 0;
  if (result > 0) {
    char delimiter = '~';
    char* pEnd = strchr(RecvBuf, delimiter);
    if (pEnd != NULL) {
      char* pColon = strchr(RecvBuf, ':');
      if (pColon != NULL) {
	// get file size.
	char* pBegin = pColon + 1;
        const int kLength = pEnd - pBegin;
	char* length_buf = (char*)malloc(kLength);
	strncpy(length_buf, pBegin, kLength);
	size = atoi(length_buf);
        free(length_buf);
	// write data to file.
	int header_length = pEnd + 1 - RecvBuf;
	int count = result - header_length;
	fwrite(pEnd + 1, sizeof(char), count, file);
	size_written += count;
      }
    }
  }

  return size;
}

int main(int argc, char** argv) {
  WSADATA data;
  int result = WSAStartup(MAKEWORD(2, 2), &data);
  if (result == 0) {
    SOCKET client_soc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (INVALID_SOCKET != client_soc) {
      sockaddr_in addr;
      unsigned short http_default_port = 80;
      addr.sin_family = AF_INET;
      addr.sin_port = htons(http_default_port);
      addr.sin_addr.s_addr = inet_addr("127.0.0.1");

      result = connect(client_soc, (sockaddr*)&addr, sizeof(addr));
      if (result == 0) {
	char file_name[] = "Torvalds.pdf";
	const int kRecvBufSize = 1024;
	char RecvBuf[kRecvBufSize] = {'\0'};
	FILE* file = fopen(file_name, "wb");
	if (file != NULL) {
	  int size_written = 0;
	  int total_size = ParseFileSize(file, client_soc, size_written);
	  while (size_written < total_size) {
	    result = recv(client_soc, RecvBuf, kRecvBufSize, 0);
	    if (result == 0) {
	      puts("recv fail.");
	      break;
	    }
	    fwrite(RecvBuf, sizeof(char), result, file);
	    memset(RecvBuf, 0, kRecvBufSize);
	    size_written += result;
	  }
	  fclose(file);
        }
      }
      closesocket(client_soc);
    }
    WSACleanup();
  }
  
  return 0;
}
